-module(spider_thread).
-behaviour(gen_server).
-export([
         start_link/2,
         refresh/1, refresh_sync/1,
         fetch/1,
         refresh_content/1
        ]).
-export([
         init/1,
         handle_call/3,
         handle_cast/2,
         handle_info/2,
         terminate/2,
         code_change/3
        ]).

-include("cloap_record.hrl").
-define(SERVER, ?MODULE).
-define(DEFAULT_LEASE_TIME, 60).  %% 60 秒自动更新
-record(state, {who, interval}).


start_link(Who, Interval) ->
    gen_server:start_link(?MODULE, [Who, Interval], []).
refresh(Pid) ->
    gen_server:cast(Pid, refresh).
refresh_sync(Pid) ->
    gen_server:call(Pid, refresh).
fetch(Pid) ->
    gen_server:call(Pid, fetch).


 
init([Who, Interval]) ->
    {ok, #state{who = Who, interval = Interval}, ?DEFAULT_LEASE_TIME * 1000}.
handle_call(fetch, _From, State) ->
    Who    = State#state.who,
    Interval = State#state.interval,
    {reply, cloap_store:find_all(todo_cache, Who), State, Interval * 1000};
handle_call(refresh, _From, State) ->
    Who    = State#state.who,
    Interval = State#state.interval,
    refresh_content(State),
    {reply, cloap_store:find_all(todo_cache, Who), State, Interval * 1000}.
handle_cast(refresh, State) ->
    refresh_content(State),
    Interval = State#state.interval,
    {noreply, State, Interval * 1000}.
handle_info(timeout, State) ->
    Interval = State#state.interval,
    refresh_content(State),
    {noreply, State, Interval * 1000}.
terminate(_Reason, State) ->
    Who    = State#state.who,
    case pdict_store:userinfo_get(Who, pid) of
        not_found  -> ok;
        _Pid       -> pdict_store:userinfo_put(Who, pid)  %% Remove pid Key
    end.
code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

 


refresh_content(State) ->
    try
        case cloap_store:find(user, {login, State#state.who}) of
            not_found ->
                [];
            Who ->
                cloap_store:delete_all(todo_cache, Who#user.login),

                Rpc = fun(Spider) ->
                              case httpc:request(
                                     binary_to_list(Spider#spider.url) ++
                                     "?login=" ++ binary_to_list(Who#user.login) ++
                                     "&&password=" ++ binary_to_list(Who#user.passwd)) of
                                  {error, Reason} ->
                                      lager:error("spider ~p ~p ~p ~n", [Spider#spider.url, Who, Reason]);
                                  {ok, {_Status, _Headers, Body}} ->
                                      Ret = jsx:decode(list_to_binary(Body)),
                                      lager:info("~p", [Ret]),

                                      Fun = fun(Rec) -> 
                                                    Category = proplists:get_value(<<"category">>,  Rec),
                                                    Subject  = proplists:get_value(<<"subject">>,   Rec, <<"">>),
                                                    Items    = proplists:get_value(<<"items">>,     Rec, []),
                                                    #todo_cache{
                                                       id        = cloap_store:uuid(), 
                                                       spider_id = Spider#spider.id, 
                                                       category  = Category, 
                                                       subject   = Subject, 
                                                       contents  = Items, 
                                                       login     = Who#user.login }
                                            end,

                                      case Ret of
                                          Ret when is_map(Ret)  ->
                                              cloap_store:insert(Fun(Ret));
                                          Ret when is_list(Ret) ->
                                              lists:foreach(fun(X) -> cloap_store:insert(Fun(X)) end, Ret)
                                      end
                              end
                      end,

                lists:map(fun(X) -> Rpc(X) end, cloap_store:find_all(spider))
        end
    catch
        _:Reason ->
            lager:error("refresh content ~p", [Reason]),
            []
    end.



